////////////////////////////////////////////////////////////////////////////////
/// @brief program options description
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2010-2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#ifndef TRIAGENS_BASICS_PROGRAM_OPTIONS_DESCRIPTION_H
#define TRIAGENS_BASICS_PROGRAM_OPTIONS_DESCRIPTION_H 1

#include "Basics/Common.h"

namespace triagens {
  namespace basics {

// -----------------------------------------------------------------------------
// --SECTION--                                   class ProgramOptionsDescription
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ProgramOptions
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief ProgramOptionsDescription
////////////////////////////////////////////////////////////////////////////////

    class ProgramOptionsDescription {
      friend class ProgramOptions;

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ProgramOptions
/// @{
////////////////////////////////////////////////////////////////////////////////

      public:

////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription ();

////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription (string const& name);

////////////////////////////////////////////////////////////////////////////////
/// @brief copy constructor
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription (ProgramOptionsDescription const&);

////////////////////////////////////////////////////////////////////////////////
/// @brief assignment constructor
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator= (ProgramOptionsDescription const&);

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ProgramOptions
/// @{
////////////////////////////////////////////////////////////////////////////////

      public:

////////////////////////////////////////////////////////////////////////////////
/// @brief changes the name
////////////////////////////////////////////////////////////////////////////////

        void setName (string const& name);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a new visible or hidden section
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (ProgramOptionsDescription&, bool hidden = false);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a new flag
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a string argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, string* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a string vector argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, vector<string>* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds an int32_t argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, int32_t* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds an int32_t vector argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, vector<int32_t>* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds an int64_t argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, int64_t* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds an int64_t vector argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, vector<int64_t>* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds an uint32_t argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, uint32_t* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds an uint32_t vector argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, vector<uint32_t>* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds an uint64_t argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, uint64_t* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds an uint64_t vector argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, vector<uint64_t>* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a double argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, double* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a double vector argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, vector<double>* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a boolean argument
////////////////////////////////////////////////////////////////////////////////

        ProgramOptionsDescription& operator() (string const& name, bool* value, string const& text);

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a time_t argument
////////////////////////////////////////////////////////////////////////////////

#if __WORDSIZE == 32
        ProgramOptionsDescription& operator() (string const& name, time_t* value, string const& text);
#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief adds positional arguments
////////////////////////////////////////////////////////////////////////////////

        void arguments (vector<string>*);

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the usage message
////////////////////////////////////////////////////////////////////////////////

        string usage () const;

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the usage message
////////////////////////////////////////////////////////////////////////////////

        string usage (set<string> const& help, bool addHelpOptions = true) const;

////////////////////////////////////////////////////////////////////////////////
/// @brief returns a list of help options
////////////////////////////////////////////////////////////////////////////////

        set<string> helpOptions () const;

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                      public types
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ProgramOptions
/// @{
////////////////////////////////////////////////////////////////////////////////

      private:

////////////////////////////////////////////////////////////////////////////////
/// @brief option types
////////////////////////////////////////////////////////////////////////////////

        enum option_type_e {
          OPTION_TYPE_FLAG,
          OPTION_TYPE_STRING,
          OPTION_TYPE_VECTOR_STRING,
          OPTION_TYPE_INT32,
          OPTION_TYPE_VECTOR_INT64,
          OPTION_TYPE_INT64,
          OPTION_TYPE_VECTOR_INT32,
          OPTION_TYPE_UINT32,
          OPTION_TYPE_VECTOR_UINT32,
          OPTION_TYPE_UINT64,
          OPTION_TYPE_VECTOR_UINT64,
          OPTION_TYPE_DOUBLE,
          OPTION_TYPE_VECTOR_DOUBLE,
          OPTION_TYPE_BOOL,
          OPTION_TYPE_TIME
        };

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ProgramOptions
/// @{
////////////////////////////////////////////////////////////////////////////////

      private:

////////////////////////////////////////////////////////////////////////////////
/// @brief checks if the name is an option, defines short/long mapping
////////////////////////////////////////////////////////////////////////////////

        string check (string const& name);

////////////////////////////////////////////////////////////////////////////////
/// @brief checks if the name is an option, defines short/long mapping
////////////////////////////////////////////////////////////////////////////////

        string check (string const& name, void* value);

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                 private variables
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ProgramOptions
/// @{
////////////////////////////////////////////////////////////////////////////////

      private:

////////////////////////////////////////////////////////////////////////////////
/// @brief name of the section
////////////////////////////////////////////////////////////////////////////////

        string _name;

////////////////////////////////////////////////////////////////////////////////
/// @brief help options
////////////////////////////////////////////////////////////////////////////////

        set<string> _helpOptions;

////////////////////////////////////////////////////////////////////////////////
/// @brief sub-descriptions
////////////////////////////////////////////////////////////////////////////////

        vector<ProgramOptionsDescription> _subDescriptions;

////////////////////////////////////////////////////////////////////////////////
/// @brief hidden sub-descriptions
////////////////////////////////////////////////////////////////////////////////

        vector<ProgramOptionsDescription> _hiddenSubDescriptions;

////////////////////////////////////////////////////////////////////////////////
/// @brief defined option names
////////////////////////////////////////////////////////////////////////////////

        vector<string> _optionNames;

////////////////////////////////////////////////////////////////////////////////
/// @brief type of an option
////////////////////////////////////////////////////////////////////////////////

        map< string, option_type_e > _optionTypes;

////////////////////////////////////////////////////////////////////////////////
/// @brief short name of an option
////////////////////////////////////////////////////////////////////////////////

        map< string, string > _long2short;

////////////////////////////////////////////////////////////////////////////////
/// @brief help text of an option
////////////////////////////////////////////////////////////////////////////////

        map< string, string > _helpTexts;

////////////////////////////////////////////////////////////////////////////////
/// @brief all string options
////////////////////////////////////////////////////////////////////////////////

        map< string, string* > _stringOptions;

////////////////////////////////////////////////////////////////////////////////
/// @brief all vector string options
////////////////////////////////////////////////////////////////////////////////

        map< string, vector<string>* > _vectorStringOptions;

////////////////////////////////////////////////////////////////////////////////
/// @brief all int32 options
////////////////////////////////////////////////////////////////////////////////

        map< string, int32_t* > _int32Options;

////////////////////////////////////////////////////////////////////////////////
/// @brief all vector int32 options
////////////////////////////////////////////////////////////////////////////////

        map< string, vector<int32_t>* > _vectorInt32Options;

////////////////////////////////////////////////////////////////////////////////
/// @brief all int64 options
////////////////////////////////////////////////////////////////////////////////

        map< string, int64_t* > _int64Options;

////////////////////////////////////////////////////////////////////////////////
/// @brief all vector int64 options
////////////////////////////////////////////////////////////////////////////////

        map< string, vector<int64_t>* > _vectorInt64Options;

////////////////////////////////////////////////////////////////////////////////
/// @brief all uint32 options
////////////////////////////////////////////////////////////////////////////////

        map< string, uint32_t* > _uint32Options;

////////////////////////////////////////////////////////////////////////////////
/// @brief all vector uint32 options
////////////////////////////////////////////////////////////////////////////////

        map< string, vector<uint32_t>* > _vectorUInt32Options;

////////////////////////////////////////////////////////////////////////////////
/// @brief all uint64 options
////////////////////////////////////////////////////////////////////////////////

        map< string, uint64_t* > _uint64Options;

////////////////////////////////////////////////////////////////////////////////
/// @brief all vector uint64 options
////////////////////////////////////////////////////////////////////////////////

        map< string, vector<uint64_t>* > _vectorUInt64Options;

////////////////////////////////////////////////////////////////////////////////
/// @brief all double options
////////////////////////////////////////////////////////////////////////////////

        map< string, double* > _doubleOptions;

////////////////////////////////////////////////////////////////////////////////
/// @brief all vector double options
////////////////////////////////////////////////////////////////////////////////

        map< string, vector<double>* > _vectorDoubleOptions;

////////////////////////////////////////////////////////////////////////////////
/// @brief all boolean options
////////////////////////////////////////////////////////////////////////////////

        map< string, bool* > _boolOptions;

////////////////////////////////////////////////////////////////////////////////
/// @brief all time options
////////////////////////////////////////////////////////////////////////////////

#if __WORDSIZE == 32
        map< string, time_t* > _timeOptions;
#endif

////////////////////////////////////////////////////////////////////////////////
/// @brief all positional arguments
////////////////////////////////////////////////////////////////////////////////

        vector<string>* _positionals;
    };
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

#endif

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
// End:
